package controllers

import (
	"fmt"
	"io/ioutil"
	"net/http"

	"time"

	"github.com/dgrijalva/jwt-go"
	"github.com/gin-gonic/gin"
	"github.com/globalsign/mgo/bson"

	"cmt1-admin/lib/request"
	"cmt1-admin/models"
)

type GameUserProto struct {
	Code    int64           `json:"code"`
	Data    models.GameUser `json:"data"`
	Msg     string          `json:"msg"`
	Success bool            `json:"success"`
}

func MyTest(c *gin.Context) {

	fmt.Println("访问成功")
	mdata := make(map[string]interface{}, 0)
	mdata["userpwd"] = ""
	mdata["username"] = "admin"
	handleOk(c, mdata)
}

func UserLogin(c *gin.Context) {
	user := new(models.User)
	if err := c.ShouldBindJSON(user); err != nil {
		handleErr(c, 500, err.Error())
		return
	}

	auser := &models.AdminUser{}
	err := GameAdminDB.FindOne("AdminUser", bson.M{"account": user.Account, "password": user.Password}, nil, &auser)
	if err != nil {
		handleErr(c, 401, "用户名或密码不对")
		return
	}

	// if user.Username != "admin" || user.Password != "111111" {
	// 	handleErr(c, 401, "用户名或密码不对")
	// 	return
	// }

	uid := bson.NewObjectId().Hex()

	token, err := NewJWT().CreateToken(CustomClaims{uid, "admin", jwt.StandardClaims{
		NotBefore: int64(time.Now().Unix() - 1000),   // 签名生效时间
		ExpiresAt: int64(time.Now().Unix() + 3600*3), // 过期时间 一小时
		Issuer:    "cmt1-server",                     //签名的发行者
	}})

	if err != nil {
		handleErr(c, 401, err.Error())
		return
	}

	mdata := make(map[string]interface{}, 0)
	mdata["uid"] = uid
	mdata["username"] = "admin"
	mdata["token"] = token
	handleOk(c, mdata)
}

func UserLogout(c *gin.Context) {
	handleOk(c, "success")
}

func UserInfo(c *gin.Context) {
	token := c.Query("token")
	fmt.Println("token = ", token)
	claims, err := NewJWT().ParseToken(token)
	if err != nil {
		handleErr(c, 401, err.Error())
		return
	}
	handleOk(c, map[string]interface{}{"name": claims.Username, "avatar": "https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif"})
}

//通过用户UID，获取用户信息
func GetUserInfoByUid(c *gin.Context) {
	uid := c.Param("uid")
	res, err := request.Get("user/uid/" + uid)
	if err != nil {
		handleErr(c, 401, err.Error())
		return
	}
	c.Writer.Header().Set("content-type", "application/json")
	c.String(http.StatusOK, string(res))
}

//获取在线人数
func GetOnlineNum(c *gin.Context) {
	res, err := request.Get("user/onlineNum")
	if err != nil {
		handleErr(c, 401, err.Error())
		return
	}
	c.Writer.Header().Set("content-type", "application/json")
	c.String(http.StatusOK, string(res))
}

// fmt.Println(c.Request.URL.Query())
// fmt.Println(c.Request.URL.RawQuery)

// uid := c.Query("uid") //查询请求URL后面的参数
// closureEndTime := c.DefaultQuery("closureEndTime", "0")
// closureLength := c.DefaultQuery("closureLength", "0") //查询请求URL后面的参数，如果没有填写默认值
// name := c.PostForm("name") //从表单中查询参数

//封禁玩家
func SetClosureTime(c *gin.Context) {
	res, err := request.Get("user/closure?" + c.Request.URL.RawQuery)
	if err != nil {
		handleErr(c, 401, err.Error())
		return
	}
	c.Writer.Header().Set("content-type", "application/json")
	c.String(http.StatusOK, string(res))
}

// 设置白名单
func SetWhite(c *gin.Context) {
	data, _ := ioutil.ReadAll(c.Request.Body)
	//转发请求，请求游戏服务器
	res, err := request.PostByte("user/white", data)
	if err != nil {
		handleErr(c, 401, err.Error())
		return
	}
	c.Writer.Header().Set("content-type", "application/json")
	c.String(http.StatusOK, string(res))
}

// 转发请求，访问游戏服务器
func GetUserList(c *gin.Context) {
	//转发到游戏服务器
	res, err := request.Get("user/list?" + c.Request.URL.RawQuery)
	if err != nil {
		handleErr(c, 401, err.Error())
		return
	}
	c.Writer.Header().Set("content-type", "application/json")
	c.String(http.StatusOK, string(res))
}

type UserModify struct {
	Uid    bson.ObjectId `form:"_uid" json:"_uid"`
	Energy int64         `form:"energy" json:"energy"` //体力
	Gold   int64         `form:"gold" json:"gold"`     //金币
	Diamon int64         `form:"diamon" json:"diamon"` //砖石
	Star   int64         `form:"star" json:"star"`     //星星数量
}

// 转发请求，访问游戏服务器
func SetUserInfo(c *gin.Context) {
	userModify := new(UserModify)
	if err := c.ShouldBindJSON(userModify); err != nil {
		handleErr(c, 404, err.Error())
		return
	}
	//转发到游戏服务器
	res, err := request.Post("user/modify", userModify)
	if err != nil {
		handleErr(c, 401, err.Error())
		return
	}
	c.Writer.Header().Set("content-type", "application/json")
	c.String(http.StatusOK, string(res))
}

type UserQuery struct {
	BaseRequest
	Name      string `form:"name"`
	AccountId string `form:"accountId"`
}

// 直接访问数据库查询用户信息
func UserList(c *gin.Context) {
	userQuery := &UserQuery{}
	if err := c.ShouldBindQuery(&userQuery); err != nil {
		handleErr(c, 404, err.Error())
		return
	}
	if userQuery.Page > 0 {
		userQuery.Page -= 1
	}
	mquery := make(map[string]interface{}, 0)
	if userQuery.Name != "" {
		mquery["name"] = userQuery.Name
	}

	if userQuery.AccountId != "" {
		mquery["accountId"] = userQuery.AccountId
	}

	count, err := GameDB.Count("user", mquery)
	if err != nil {
		handleErr(c, 404, err.Error())
		return
	}
	users := make([]*models.GameUser, 0)
	err = GameDB.FindPage("user", userQuery.Page, userQuery.PageNum, mquery, nil, &users)
	if err != nil {
		handleErr(c, 404, err.Error())
		return
	}
	handleOk(c, map[string]interface{}{"users": users, "count": count})
}

type ChartQuery struct {
	STime  int64 `form:"sTime"`
	ETime  int64 `form:"eTime"`
	Operat int64 `form:"operat"` // 1.每天 2.每月
}

// 新增玩家数
func GetNewUser(c *gin.Context) {
	q := &ChartQuery{}
	if err := c.ShouldBindQuery(&q); err != nil {
		handleErr(c, 404, err.Error())
		return
	}

	if q.STime <= 0 || q.ETime <= 0 || q.STime > q.ETime {
		handleErr(c, 404, "时间格式不对")
		return
	}

	vgroup := bson.M{
		"_id":   bson.M{"year": bson.M{"$year": "$time"}, "month": bson.M{"$month": "$time"}, "day": bson.M{"$dayOfMonth": "$time"}},
		"count": bson.M{"$sum": 1},
	}
	vsort := bson.M{"_id.year": 1, "_id.month": 1, "_id.day": 1}
	if q.Operat == 2 {
		vgroup = bson.M{
			"_id":   bson.M{"year": bson.M{"$year": "$time"}, "month": bson.M{"$month": "$time"}},
			"count": bson.M{"$sum": 1},
		}
		vsort = bson.M{"_id.year": 1, "_id.month": 1}
	}

	var pipeline []bson.M
	pipeline = []bson.M{
		{"$match": bson.M{"registerTime": bson.M{"$gte": q.STime, "$lte": q.ETime}}},                                                            // 过滤时间
		{"$project": bson.M{"_id": 1, "registerTime": 1, "time": bson.M{"$toDate": bson.M{"$multiply": []interface{}{"$registerTime", 1000}}}}}, // 将时间戳转时间
		{"$group": vgroup},
		{"$sort": vsort},
	}

	lst := make([]interface{}, 0)
	err := GameLogDB.PipeAll("user", pipeline, &lst, false) // 查询新增玩家数
	if err != nil {
		handleErr(c, 404, err.Error())
		return
	}

	handleOk(c, map[string]interface{}{"list": lst})
}

// 付费玩家数
func GetPayUser(c *gin.Context) {
	q := &ChartQuery{}
	if err := c.ShouldBindQuery(&q); err != nil {
		handleErr(c, 404, err.Error())
		return
	}

	if q.STime <= 0 || q.ETime <= 0 || q.STime > q.ETime {
		handleErr(c, 404, "时间格式不对")
		return
	}

	vgroup := bson.M{ // 按照年月日分组，统计每天充值玩家的数量
		"_id":   bson.M{"year": bson.M{"$year": "$time"}, "month": bson.M{"$month": "$time"}, "day": bson.M{"$dayOfMonth": "$time"}},
		"count": bson.M{"$sum": 1},
	}
	vsort := bson.M{"_id.year": 1, "_id.month": 1, "_id.day": 1}
	if q.Operat == 2 {
		vgroup = bson.M{
			"_id":   bson.M{"year": bson.M{"$year": "$time"}, "month": bson.M{"$month": "$time"}},
			"count": bson.M{"$sum": 1},
		}
		vsort = bson.M{"_id.year": 1, "_id.month": 1}
	}

	var pipeline []bson.M
	pipeline = []bson.M{
		{"$match": bson.M{"orderTime": bson.M{"$gte": q.STime, "$lte": q.ETime}}},                                         // 过滤时间
		{"$project": bson.M{"_id": 1, "time": bson.M{"$toDate": bson.M{"$multiply": []interface{}{"$orderTime", 1000}}}}}, // 将时间戳转时间
		{"$group": vgroup},
		{"$sort": vsort},
	}
	lst := make([]interface{}, 0)
	err := GameLogDB.PipeAll("PayOrder", pipeline, &lst, false) // 查询充值玩家数
	if err != nil {
		handleErr(c, 404, err.Error())
		return
	}
	handleOk(c, map[string]interface{}{"list": lst})
}

// 收入
func GetIncome(c *gin.Context) {
	q := &ChartQuery{}
	if err := c.ShouldBindQuery(&q); err != nil {
		handleErr(c, 404, err.Error())
		return
	}

	if q.STime <= 0 || q.ETime <= 0 || q.STime > q.ETime {
		handleErr(c, 404, "时间格式不对")
		return
	}

	vgroup := bson.M{ // 按照年月日分组，统计每天收入
		"_id":   bson.M{"year": bson.M{"$year": "$time"}, "month": bson.M{"$month": "$time"}, "day": bson.M{"$dayOfMonth": "$time"}},
		"count": bson.M{"$sum": "$amount"},
	}
	vsort := bson.M{"_id.year": 1, "_id.month": 1, "_id.day": 1}
	if q.Operat == 2 {
		vgroup = bson.M{
			"_id":   bson.M{"year": bson.M{"$year": "$time"}, "month": bson.M{"$month": "$time"}},
			"count": bson.M{"$sum": "$amount"},
		}
		vsort = bson.M{"_id.year": 1, "_id.month": 1}
	}

	var pipeline []bson.M
	pipeline = []bson.M{
		{"$match": bson.M{"orderTime": bson.M{"$gte": q.STime, "$lte": q.ETime}}},                                                      // 过滤时间
		{"$project": bson.M{"_id": 1, "amount": 1, "time": bson.M{"$toDate": bson.M{"$multiply": []interface{}{"$orderTime", 1000}}}}}, // 将时间戳转时间
		{"$group": vgroup},
		{"$sort": vsort},
	}
	lst := make([]interface{}, 0)
	err := GameLogDB.PipeAll("PayOrder", pipeline, &lst, false) // 查询收入
	if err != nil {
		handleErr(c, 404, err.Error())
		return
	}
	handleOk(c, map[string]interface{}{"list": lst})
}
